#!/usr/bin/python3
# -*- coding: utf-8 -*-

from utils import find_files, Singleton, read_json, save_json
from strategies import *
from pprint import pprint
from parse import *
from fuzzywuzzy import process


@Singleton
def load_fields():
    return read_json(path="parseFields.json")


def fuzzy_search(field, choices, l_offset=0, r_offset=5):
    """
    该函数功能为：在指定备选TABLES中模糊搜寻与指定字段最相似的字符串， 根据左右偏移参数取相似备选TABLES

    Parameters
    ----------
    field
    choices
    l_offset
    r_offset

    Returns
    -------

    """
    if not choices:
        return []
    fields = load_fields()
    field = sorted(
        [process.extractOne(f, choices=choices) for f in fields[field]],
        key=lambda x: x[1],
        reverse=True
    )[0][0]
    ind = choices.index(field)
    if ind - l_offset < 0:
        start = 0
        prefix = ["" for _ in range(abs(ind - l_offset))]
    else:
        start = ind - l_offset
        prefix = []
    if ind + r_offset > len(choices):
        end = len(choices)
        suffix = ["" for _ in range(ind + r_offset - len(choices))]
    else:
        end = ind + r_offset + 1
        suffix = []
    return prefix + choices[start: end] + suffix


def main():
    for file_path in find_files(path="待识别数据", pattern="*.pdf"):
        # 打印文件路径
        print(file_path)
        # test
        # words = load_pdfplumber_words(path=file_path)
        # # print(words)

        # 载入pdf文件的文本数据TABLES
        texts = load_pdfplumber_texts(path=file_path)
        # 载入pdf文件的表格数据TABLES
        tables = load_pdfplumber_tables(path=file_path)
        print("pdfplumber texts: ", texts)
        print("pdfplumber tables: ", tables)

        # 保单号搜寻并且匹配
        insurance_numbers = fuzzy_search("保单号", texts, 0, 25)
        print("保单号TEXTS：", insurance_numbers)
        insurance_number = insurance_numbers_strategy(choices=insurance_numbers)

        # 被保险人名称搜寻并且匹配
        insurance_peoples = fuzzy_search("被保险人名称", tables, 3, 10)
        print("被保险人名称TABLES：", insurance_peoples)
        order = 1 if "太平财产保险有限公司" in "".join(texts) else -1
        print("order: ", order)
        insurance_people = insurance_peoples_strategy(choices=insurance_peoples, importance=3, order=order)
        if not insurance_people or insurance_people == "签单公司":
            insurance_peoples = fuzzy_search("被保险人名称", texts, 5, 10)
            print("被保险人名称TEXTS：", insurance_peoples)
            insurance_people = insurance_peoples_strategy(choices=insurance_peoples, importance=5, order=order)

        # 保险期间搜寻并且匹配
        insurance_dates = fuzzy_search("保险期间", tables, 0, 10)
        print("保险期间TABLES：", insurance_dates)
        insurance_date = insurance_dates_strategy(choices=insurance_dates)
        none_num = sum([1 for date in insurance_date if not date])

        if none_num:
            tables_backup = load_tabula_tables(path=file_path)
            print("备用方法Tables", tables_backup)
            insurance_dates_backup = fuzzy_search("保险期间", tables_backup, 0, 10)
            print("保险期间(备用方法)TABLES：", insurance_dates_backup)
            insurance_date_backup = insurance_dates_strategy(choices=insurance_dates_backup)
            none_num_backup = sum([1 for date in insurance_date_backup if not date])
            if none_num_backup < none_num:
                insurance_date = insurance_date_backup
        none_num = sum([1 for date in insurance_date if not date])
        if none_num:
            insurance_dates = fuzzy_search("保险期间", texts, 0, 20)
            print("保险期间TEXTS：", insurance_dates)
            insurance_date_backup1 = insurance_dates_strategy(choices=insurance_dates)
            none_num_backup1 = sum([1 for date in insurance_date_backup1 if not date])
            if none_num_backup1 < none_num:
                insurance_date = insurance_date_backup1

        # 保单总保费搜寻并且匹配
        insurance_expands = fuzzy_search("保单总保费", tables, 3)
        print("保单总保费TABLES：", insurance_expands)
        insurance_expand = insurance_expands_strategy(choices=insurance_expands)
        if not insurance_expand:
            insurance_expands = fuzzy_search("保单总保费", texts, 3)
            print("保单总保费TEXTS：", insurance_expands)
            insurance_expand = insurance_expands_strategy(choices=insurance_expands)

        # 车牌号码搜寻并且匹配
        license_plate_numbers = fuzzy_search("车牌号码", tables, 2, 7)
        print("车牌号码TABLES：", license_plate_numbers)
        license_plate_number = license_plate_numbers_strategy(choices=license_plate_numbers, importance=2)
        if not license_plate_number:
            license_plate_numbers = fuzzy_search("车牌号码", texts, 2, 7)
            print("车牌号码TEXTS：", license_plate_numbers)
            license_plate_number = license_plate_numbers_strategy(choices=license_plate_numbers, importance=2)

        # 发动机号搜寻并且匹配
        engine_numbers = fuzzy_search("发动机号", tables, 2)
        print("发动机号TABLES：", engine_numbers)
        engine_number = engine_numbers_strategy(choices=engine_numbers, importance=2)
        if not engine_number or engine_number == "95505":
            engine_numbers = fuzzy_search("发动机号", texts, 2)
            print("发动机号TEXTS：", engine_numbers)
            engine_number = engine_numbers_strategy(choices=engine_numbers, importance=2)

        # 车架号搜寻并且匹配
        frame_numbers = fuzzy_search("车架号", tables, 2)
        print("车架号TABLES：", frame_numbers)
        frame_number = frame_numbers_strategy(choices=frame_numbers, importance=2)
        if not frame_number or ("www" in frame_number and "com" in frame_number):
            frame_numbers = fuzzy_search("车架号", texts, 2)
            print("车架号TEXTS：", frame_numbers)
            frame_number = frame_numbers_strategy(choices=frame_numbers, importance=2)

        recognize_response = {
            "保单号": insurance_number,
            "被保险人名称": insurance_people,
            "保险责任开始时间": insurance_date[0],
            "保险责任结束时间": insurance_date[1],
            "保单总保费": insurance_expand,
            "车牌号码": license_plate_number,
            "发动机号": engine_number,
            "车架号": frame_number
        }
        # todo：采用其他的读取的方式来读取表格数据，如果recognize_response大部分为空
        pprint(recognize_response)

        save_name = file_path.replace("\\", "/").split("/")[-1].split(".")[0]
        # 将识别结果存入文件
        save_json(path=f'识别结果/{save_name}.json', d=recognize_response)

        print("=" * 80)


if __name__ == '__main__':
    """
    Python3.8环境
    """
    main()
